package com.aiwiown.snackmq.cluster.metadata;

import com.aiwiown.snackmq.common.cluster.BrokerId;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 主题的元数据，现在包含了详细的分区分配信息。
 */
@Getter
@Setter
@ToString
public class TopicMetadata implements Serializable {

    private static final long serialVersionUID = 6474656728118010274L;
    // 主题名称，是 TopicMetadata 的核心属性之一
    private final String topicName;
    //【新增字段】存储该 Topic 的副本因子，决定了每个分区的副本数量
    private int replicationFactor = 1;
    // 使用分区ID作为键，存储每个分区的详细分配信息
    private final Map<Integer, PartitionAssignment> partitionAssignments = new ConcurrentHashMap<>();

    /**
     * 构造函数，初始化主题名称。
     * @param topicName 主题名称
     */
    public TopicMetadata(String topicName) {
        this.topicName = topicName;
    }

    /**
     * 获取分区数量。
     * @return 分区数量
     */
    public int getPartitionCount() {
        return this.partitionAssignments.size();
    }

    /**
     * 设置分区的分配信息。
     * @param partitionId 分区ID
     * @param assignment 分区的分配信息
     */
    public void setPartitionAssignment(int partitionId, PartitionAssignment assignment) {
        this.partitionAssignments.put(partitionId, assignment);
    }

    /**
     * 获取指定分区的分配信息。
     * @param partitionId 分区ID
     * @return 分区的分配信息
     */
    public PartitionAssignment getAssignmentFor(int partitionId) {
        return this.partitionAssignments.get(partitionId);
    }

    /**
     * 代表单个分区的分配信息，包括其副本列表和当前的 Leader。
     */
    @Getter
    @Setter
    @AllArgsConstructor
    @ToString
    public static class PartitionAssignment implements Serializable {
        private static final long serialVersionUID = 3500630641422180566L;
        // 分区的副本列表，包括所有的Broker副本
        private List<BrokerId> replicas;
        // 当前分区的 Leader Broker
        private BrokerId leader;
    }
}
